package com.ssy.lingxi.marketing.serviceimpl.base.activity;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.member.MemberRoleEnum;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.common.utils.DateTimeUtil;
import com.ssy.lingxi.marketing.entity.activity.*;
import com.ssy.lingxi.marketing.model.bo.PfActivitySignUpPageBO;
import com.ssy.lingxi.marketing.model.constant.*;
import com.ssy.lingxi.marketing.model.vo.activity.request.PfActivitySignUpPageReq;
import com.ssy.lingxi.marketing.model.vo.activity.request.PlatformActivityBaseReq;
import com.ssy.lingxi.marketing.model.vo.activity.request.PlatformActivityCommonPageVO;
import com.ssy.lingxi.marketing.model.vo.activity.request.PlatformActivityInviteReq;
import com.ssy.lingxi.marketing.model.vo.activity.response.PlatformActivityInviteResp;
import com.ssy.lingxi.marketing.repository.PlatformActivityInviteRepository;
import com.ssy.lingxi.marketing.repository.PlatformActivityRepository;
import com.ssy.lingxi.marketing.repository.PlatformActivitySignUpRepository;
import com.ssy.lingxi.marketing.service.IProcessFeignService;
import com.ssy.lingxi.marketing.service.IScheduleFeignService;
import com.ssy.lingxi.marketing.utils.NumberUtil;
import com.ssy.lingxi.workflow.api.model.contant.ProcessTaskStatusEnum;
import com.ssy.lingxi.workflow.api.model.vo.request.TaskExecuteVO;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleTaskCompleteVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 基础平台活动服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2021/8/16
 */
@Slf4j
@Service
public class BasePlatformActivityService extends BaseActivityService {

    @Resource
    private PlatformActivityRepository platformActivityRepository;
    @Resource
    private IProcessFeignService processFeignService;
    @Resource
    private PlatformActivitySignUpRepository signUpRepository;
    @Resource
    private PlatformActivityInviteRepository inviteRepository;
    @Resource
    private JPAQueryFactory queryFactory;
    @Resource
    private BaseActivityRecordService activityRecordService;
    @Resource
    private IScheduleFeignService scheduleFeignService;

    /**
     * 查询邀请会员报名
     * @param activityId 平台活动id
     */
    protected List<PlatformActivityInviteResp> listInvite(Long activityId) {
        if (Objects.isNull(activityId)) {
            return Collections.emptyList();
        }

        List<PlatformActivityInviteDO> inviteDOList = inviteRepository.findByPlatformActivityId(activityId);
        List<PlatformActivityInviteResp> inviteRespList = inviteDOList.stream().map(e -> {
            PlatformActivityInviteResp platformActivityInviteResp = new PlatformActivityInviteResp();
            platformActivityInviteResp.setId(e.getId());
            platformActivityInviteResp.setMemberId(e.getMemberId());
            platformActivityInviteResp.setMemberName(e.getMemberName());
            platformActivityInviteResp.setRoleId(e.getRoleId());
            platformActivityInviteResp.setRoleName(e.getRoleName());
            platformActivityInviteResp.setLevel(e.getLevel());
            platformActivityInviteResp.setLevelName(e.getLevelName());
            return platformActivityInviteResp;
        }).collect(Collectors.toList());

        return inviteRespList;
    }

    /**
     * 保存邀请会员报名
     * @param platformActivityDO 平台活动
     * @param inviteList 邀请会员集合
     */
    protected void saveInvite(PlatformActivityDO platformActivityDO, List<PlatformActivityInviteReq> inviteList) {
        if (CollectionUtils.isEmpty(inviteList)) {
            return;
        }
        // 邀请报名参加会员
        List<PlatformActivityInviteDO> inviteDOList = inviteList.stream().map(e -> {
            PlatformActivityInviteDO inviteDO = new PlatformActivityInviteDO();
            inviteDO.setPlatformActivity(platformActivityDO);
            inviteDO.setMemberId(e.getMemberId());
            inviteDO.setMemberName(e.getMemberName());
            inviteDO.setRoleId(e.getRoleId());
            inviteDO.setRoleName(e.getRoleName());
            inviteDO.setLevel(e.getLevel());
            inviteDO.setLevelName(e.getLevelName());
            return inviteDO;
        }).collect(Collectors.toList());
        inviteRepository.saveAll(inviteDOList);
    }

    /**
     * 删除邀请会员报名
     * @param activityId 平台活动id
     */
    protected void deleteInvite(Long activityId) {
        if (Objects.isNull(activityId)) {
            return;
        }
        inviteRepository.deleteByPlatformActivityId(activityId);
    }

    /**
     * 平台活动参数校验
     * @param activitySignUpType  活动参与类型
     * @param request 请求参数
     * @return 返回结果
     */
    protected Wrapper<Void> checkPlatformParam(Integer activitySignUpType, PlatformActivityBaseReq request) {
        // 当前时间
        long currentTimeMillis = System.currentTimeMillis();

        // 判断活动时间
        Wrapper<Void> checkTimeWrapper = this.checkPlatformActivityTime(currentTimeMillis, request.getStartTime(), request.getEndTime());
        if (ResponseCode.SUCCESS.getCode() != checkTimeWrapper.getCode()) {
            return checkTimeWrapper;
        }

        // 商家报名活动
        if (ActivitySignUpTypeEnum.SUPPLIER.getCode().equals(activitySignUpType)) {
            // 判断活动报名时间
            Wrapper<Void> checkSignUptTimeWrapper = this.checkPlatformActivitySignUpTime(request.getStartTime(), request.getSignUpStartTime(), request.getSignUpEndTime());
            if (ResponseCode.SUCCESS.getCode() != checkSignUptTimeWrapper.getCode()) {
                return checkSignUptTimeWrapper;
            }

            // 未勾选邀请全部, 不能没有会员
            if (CommonBooleanEnum.NO.getCode().equals(request.getInviteType())) {
                if (CollectionUtils.isEmpty(request.getInviteList())) {
                    return Wrapper.fail(ResponseCode.MARKETING_PLATFORM_ACTIVITY_INVITE_MEMBER_ERROR);
                }
            }
        }

        return Wrapper.success();
    }

    /**
     * 判断活动时间
     * @param currentTimeMillis 当前时间
     * @param startTime 活动开始时间
     * @param endTime 活动结束时间
     * @return 返回结果
     */
    protected Wrapper<Void> checkPlatformActivityTime(Long currentTimeMillis, Long startTime, Long endTime) {
        return this.checkActivityTime(currentTimeMillis, startTime, endTime);
    }

    /**
     * 判断活动报名时间
     * @param startTime 活动开始时间
     * @param signUpStartTime 活动报名时间开始
     * @param signUpEndTime 活动报名时间结束
     * @return 返回结果
     */
    protected Wrapper<Void> checkPlatformActivitySignUpTime(Long startTime, Long signUpStartTime, Long signUpEndTime) {
        // 判断报名时间
        if (Objects.isNull(signUpStartTime) || Objects.isNull(signUpEndTime)) {
            return Wrapper.fail(ResponseCode.MARKETING_PLATFORM_SIGN_UP_START_END_TIME_NOT_NULL);
        }

        // 活动开始时间要大于活动报名结束时间
        if (signUpEndTime >= startTime) {
            return Wrapper.fail(ResponseCode.MARKETING_PLATFORM_ACTIVITY_START_TIME_GE_SIGN_UP_END_TIME);
        }

        // 活动报名结束时间要大于活动报名开始时间
        if (signUpStartTime >= signUpEndTime) {
            return Wrapper.fail(ResponseCode.MARKETING_PLATFORM_SIGN_UP_END_TIME_GE_SIGN_UP_START_TIME);
        }

        return Wrapper.success();
    }

    /**
     * 平台活动公共分页列表
     *
     * @param loginUser       登录用户信息
     * @param pageVO          接口参数
     * @param outerStatus 外部状态
     * @param innerStatus 内部状态
     * @return 返回结果
     */
    protected Page<PlatformActivityDO> basePlatformActivityPage(UserLoginCacheDTO loginUser, PlatformActivityCommonPageVO pageVO, Integer outerStatus, Integer innerStatus) {
        // 组装查询条件
        Specification<PlatformActivityDO> spec = (root, query, cb) -> {
            List<Predicate> list = new ArrayList<>();
            if (Objects.nonNull(pageVO.getId())) {
                list.add(cb.equal(root.get("id").as(Long.class), pageVO.getId()));
            }
            // 组装外部状态条件
            if (NumberUtil.notNullOrZero(outerStatus)) {
                list.add(cb.in(root.get("outerStatus")).value(outerStatus));
            }
            if (NumberUtil.notNullOrZero(pageVO.getOuterStatus())) {
                list.add(cb.equal(root.get("outerStatus").as(Integer.class), pageVO.getOuterStatus()));
            }

            // 组装内部状态条件

            if (NumberUtil.notNullOrZero(innerStatus)) {
                list.add(cb.in(root.get("innerStatus")).value(innerStatus));
            }
            if (NumberUtil.notNullOrZero(pageVO.getInnerStatus())) {
                list.add(cb.equal(root.get("innerStatus").as(Integer.class), pageVO.getInnerStatus()));
            }

            if (StringUtils.isNotEmpty(pageVO.getStartTime())) {
                Long startTime = DateTimeUtil.toMilliSecond(DateTimeUtil.parseDateStart(pageVO.getStartTime()));
                list.add(cb.greaterThanOrEqualTo(root.get("startTime").as(Long.class), startTime));
            }

            if (StringUtils.isNotEmpty(pageVO.getEndTime())) {
                Long endTime = DateTimeUtil.toMilliSecond(DateTimeUtil.parseDateEnd(pageVO.getEndTime()));
                list.add(cb.lessThanOrEqualTo(root.get("endTime").as(Long.class), endTime));
            }

            if (StringUtils.isNotEmpty(pageVO.getActivityName())) {
                list.add(cb.like(root.get("activityName").as(String.class), "%" + pageVO.getActivityName().trim() + "%"));
            }

            if (Objects.nonNull(pageVO.getActivityType())) {
                list.add(cb.equal(root.get("activityType").as(Integer.class), pageVO.getActivityType()));
            }

            Predicate[] p = new Predicate[list.size()];
            return cb.and(list.toArray(p));
        };

        // 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("startTime").descending());

        return platformActivityRepository.findAll(spec, page);
    }

    /**
     * 平台活动 - 商家活动执行列表
     *
     * @param loginUser 登录用户信息
     * @param pageReq   接口参数
     * @return 返回结果
     */
    protected PageData<PfActivitySignUpPageBO> pageExecuteByMerchant(UserLoginCacheDTO loginUser, PfActivitySignUpPageReq pageReq, Integer outerStatus) {
        // 平台活动不支持渠道会员
        if (!this.checkMemberSupport(loginUser)) {
            return new PageData<>(0L, new ArrayList<>());
        }

        // 当前时间
        long currentTimeMillis = System.currentTimeMillis();

        QPlatformActivityDO activityDO = QPlatformActivityDO.platformActivityDO;
        QPlatformActivitySignUpDO signUpDO = QPlatformActivitySignUpDO.platformActivitySignUpDO;
        QPlatformActivityInviteDO inviteDO = QPlatformActivityInviteDO.platformActivityInviteDO;

        BooleanBuilder predicates = new BooleanBuilder();

        // 报名类型为商家活动
        predicates.and(activityDO.activitySignUpType.eq(ActivitySignUpTypeEnum.SUPPLIER.getCode()));


        //外部状态为待上线活动、活动进行、活动终止、活动结束、活动取消状态的平台活动
        List<Integer> merchantExecuteStatusList = PlatformActivityOuterStatusEnum.getMerchantExecuteStatusList();
        if(NumberUtil.notNullOrZero(outerStatus)){
            if(merchantExecuteStatusList.contains(outerStatus)){
                merchantExecuteStatusList=Collections.singletonList(outerStatus);
            }
        }
        predicates.and(activityDO.outerStatus.in(merchantExecuteStatusList));

        //报名审核通过的
        predicates.and(signUpDO.outerExtendStatus.eq(PlatformActivitySignUpOuterStatusEnum.SIGN_UP_PASS.getCode()));

        // 子查询 - 邀请会员
        BooleanBuilder inviteDOSubPredicates = new BooleanBuilder();
        inviteDOSubPredicates.and(
                inviteDO.platformActivity.id.eq(activityDO.id).and(
                        inviteDO.memberId.eq(loginUser.getMemberId())
                                .and(inviteDO.roleId.eq(loginUser.getMemberRoleId()))
                )
        );

        // 如果指定邀请会员,判断邀请名单, 否则不判断
        predicates.and(activityDO.inviteType.eq(CommonBooleanEnum.NO.getCode())
                .and(JPAExpressions.select(inviteDO).from(inviteDO).where(inviteDOSubPredicates).exists())
                .or(activityDO.inviteType.eq(CommonBooleanEnum.YES.getCode())));

        if (StringUtils.isNotEmpty(pageReq.getStartTime())) {
            Long startTime = DateTimeUtil.toMilliSecond(DateTimeUtil.parseDateStart(pageReq.getStartTime()));
            predicates.and(activityDO.startTime.goe(startTime));
        }

        if (StringUtils.isNotEmpty(pageReq.getEndTime())) {
            Long endTime = DateTimeUtil.toMilliSecond(DateTimeUtil.parseDateEnd(pageReq.getEndTime()));
            predicates.and(activityDO.startTime.loe(endTime));
        }

        if (StringUtils.isNotEmpty(pageReq.getActivityName())) {
            predicates.and(activityDO.activityName.like("%" + pageReq.getActivityName().trim() + "%"));
        }

        if (Objects.nonNull(pageReq.getId())) {
            predicates.and(activityDO.id.eq(pageReq.getId()));
        }

        if (Objects.nonNull(pageReq.getActivityType())) {
            predicates.and(activityDO.activityType.eq(pageReq.getActivityType()));
        }

        JPAQuery<PfActivitySignUpPageBO> queryJpaQuery = queryFactory.select(Projections.bean(PfActivitySignUpPageBO.class,
                activityDO.id.as("activityId"),
                activityDO.activityName,
                activityDO.activityType,
                activityDO.outerStatus.as("activityOuterStatus"),
                activityDO.startTime,
                activityDO.endTime,
                activityDO.signUpStartTime,
                activityDO.signUpEndTime,
                activityDO.createTime.as("activityCreateTime"),
                signUpDO.id.as("signUpId"),
                signUpDO.memberId.as("signUpMemberId"),
                signUpDO.roleId.as("signUpRoleId"),
                signUpDO.outerExtendStatus.as("signUpOuterExtendStatus"),
                signUpDO.status.as("signUpInnerStatus"),
                signUpDO.createTime.as("signUpCreateTime")))
                .from(activityDO)
                .leftJoin(signUpDO).on(activityDO.id.eq(signUpDO.platformActivity.id).and(signUpDO.memberId.eq(loginUser.getMemberId()).and(signUpDO.roleId.eq(loginUser.getMemberRoleId()))));

        queryJpaQuery.where(predicates);

        //总条数
        long totalCount = queryJpaQuery.fetchCount();
        List<PfActivitySignUpPageBO> pageList = queryJpaQuery.orderBy(activityDO.createTime.desc())
                .offset(pageReq.getCurrentOffset())
                .limit(pageReq.getPageSize())
                .fetch();

        return new PageData<>(totalCount, pageList);
    }

    /**
     * 平台活动 - 商家报名公共列表
     *
     * @param loginUser 登录用户信息
     * @param pageReq   接口参数
     * @return 返回结果
     */
    protected PageData<PfActivitySignUpPageBO> baseActivitySingUpPage(UserLoginCacheDTO loginUser, PfActivitySignUpPageReq pageReq, Integer outerStatus, Integer innerStatus) {
        // 平台活动不支持渠道会员
        if (!this.checkMemberSupport(loginUser)) {
            return new PageData<>(0L, new ArrayList<>());
        }

        // 当前时间
        long currentTimeMillis = System.currentTimeMillis();

        QPlatformActivityDO activityDO = QPlatformActivityDO.platformActivityDO;
        QPlatformActivitySignUpDO signUpDO = QPlatformActivitySignUpDO.platformActivitySignUpDO;
        QPlatformActivityInviteDO inviteDO = QPlatformActivityInviteDO.platformActivityInviteDO;

        BooleanBuilder predicates = new BooleanBuilder();

        // 报名类型为商家活动
        predicates.and(activityDO.activitySignUpType.eq(ActivitySignUpTypeEnum.SUPPLIER.getCode()));

        // 平台已提交
        predicates.and(activityDO.outerStatus.ne(PlatformActivityOuterStatusEnum.TO_BE_SUBMIT.getCode()));

        // 外部状态
        if (NumberUtil.notNullOrZero(outerStatus)) {
            if (PlatformActivitySignUpOuterStatusEnum.SIGN_UP_PASS.getCode().equals(outerStatus)) {
                BooleanBuilder signDOPredicates = new BooleanBuilder();
                signDOPredicates.and(activityDO.outerStatus.eq(PlatformActivityOuterStatusEnum.TO_BE_EXAMINE_SIGN_UP.getCode()));
                signDOPredicates.and(signUpDO.outerExtendStatus.eq(PlatformActivitySignUpOuterStatusEnum.SIGN_UP_PASS.getCode()));
                predicates.and(signDOPredicates);
            } else if (PlatformActivitySignUpOuterStatusEnum.SIGN_UP_NO_PASS.getCode().equals(outerStatus)) {
                BooleanBuilder signDOPredicates = new BooleanBuilder();
                signDOPredicates.and(activityDO.outerStatus.eq(PlatformActivityOuterStatusEnum.TO_BE_EXAMINE_SIGN_UP.getCode()));
                signDOPredicates.and(signUpDO.outerExtendStatus.eq(PlatformActivitySignUpOuterStatusEnum.SIGN_UP_NO_PASS.getCode()));
                predicates.and(signDOPredicates);
            } else {
                predicates.and(activityDO.outerStatus.eq(outerStatus));
            }
        }

        // 子查询 - 邀请会员
        BooleanBuilder inviteDOSubPredicates = new BooleanBuilder();
        inviteDOSubPredicates.and(
                inviteDO.platformActivity.id.eq(activityDO.id).and(
                        inviteDO.memberId.eq(loginUser.getMemberId())
                                .and(inviteDO.roleId.eq(loginUser.getMemberRoleId()))
                )
        );

        // 如果指定邀请会员,判断邀请名单, 否则不判断
        predicates.and(activityDO.inviteType.eq(CommonBooleanEnum.NO.getCode())
                .and(JPAExpressions.select(inviteDO).from(inviteDO).where(inviteDOSubPredicates).exists())
                .or(activityDO.inviteType.eq(CommonBooleanEnum.YES.getCode())));

        // 活动报名时间内显示有邀请的, 活动报名结束后显示已报名的
        predicates.and(activityDO.signUpStartTime.loe(currentTimeMillis).and(activityDO.signUpEndTime.goe(currentTimeMillis))
                .or(activityDO.signUpEndTime.lt(currentTimeMillis).and(signUpDO.id.isNotNull())));

        // 内部状态
        if (NumberUtil.notNullOrZero(innerStatus)) {
            if (PlatformActivitySignUpInnerStatusEnum.TO_BE_SUBMIT_EXAMINE.getCode().equals(innerStatus)) {
                predicates.and(signUpDO.status.eq(innerStatus).or(signUpDO.id.isNull()));
            } else {
                predicates.and(signUpDO.status.eq(innerStatus));
            }
        }

        if (StringUtils.isNotEmpty(pageReq.getStartTime())) {
            Long startTime = DateTimeUtil.toMilliSecond(DateTimeUtil.parseDateStart(pageReq.getStartTime()));
            predicates.and(activityDO.startTime.goe(startTime));
        }

        if (StringUtils.isNotEmpty(pageReq.getEndTime())) {
            Long endTime = DateTimeUtil.toMilliSecond(DateTimeUtil.parseDateEnd(pageReq.getEndTime()));
            predicates.and(activityDO.startTime.loe(endTime));
        }

        if (StringUtils.isNotEmpty(pageReq.getActivityName())) {
            predicates.and(activityDO.activityName.like("%" + pageReq.getActivityName().trim() + "%"));
        }

        if (Objects.nonNull(pageReq.getId())) {
            predicates.and(activityDO.id.eq(pageReq.getId()));
        }

        if (Objects.nonNull(pageReq.getActivityType())) {
            predicates.and(activityDO.activityType.eq(pageReq.getActivityType()));
        }

        JPAQuery<PfActivitySignUpPageBO> queryJpaQuery = queryFactory.select(Projections.bean(PfActivitySignUpPageBO.class,
                activityDO.id.as("activityId"),
                activityDO.activityName,
                activityDO.activityType,
                activityDO.outerStatus.as("activityOuterStatus"),
                activityDO.startTime,
                activityDO.endTime,
                activityDO.signUpStartTime,
                activityDO.signUpEndTime,
                activityDO.createTime.as("activityCreateTime"),
                signUpDO.id.as("signUpId"),
                signUpDO.memberId.as("signUpMemberId"),
                signUpDO.roleId.as("signUpRoleId"),
                signUpDO.outerExtendStatus.as("signUpOuterExtendStatus"),
                signUpDO.status.as("signUpInnerStatus"),
                signUpDO.createTime.as("signUpCreateTime")))
                .from(activityDO)
                .leftJoin(signUpDO).on(activityDO.id.eq(signUpDO.platformActivity.id).and(signUpDO.memberId.eq(loginUser.getMemberId()).and(signUpDO.roleId.eq(loginUser.getMemberRoleId()))));

        queryJpaQuery.where(predicates);

        //总条数
        long totalCount = queryJpaQuery.fetchCount();
        List<PfActivitySignUpPageBO> pageList = queryJpaQuery.orderBy(activityDO.createTime.desc())
                .offset(pageReq.getCurrentOffset())
                .limit(pageReq.getPageSize())
                .fetch();

        return new PageData<>(totalCount, pageList);
    }

    /**
     * 平台活动 - 待提交审核资料列表
     *
     * @param loginUser 登录用户信息
     * @param pageReq   接口参数
     * @return 返回结果
     */
    protected PageData<PfActivitySignUpPageBO> baseToBeSubmitActivitySingUpPage(UserLoginCacheDTO loginUser, PfActivitySignUpPageReq pageReq) {
        // 平台活动不支持渠道会员
        if (!this.checkMemberSupport(loginUser)) {
            return new PageData<>(0L, new ArrayList<>());
        }

        QPlatformActivityDO activityDO = QPlatformActivityDO.platformActivityDO;
        QPlatformActivitySignUpDO signUpDO = QPlatformActivitySignUpDO.platformActivitySignUpDO;
        QPlatformActivityInviteDO inviteDO = QPlatformActivityInviteDO.platformActivityInviteDO;

        BooleanBuilder predicates = new BooleanBuilder();

        // 报名类型为商家活动
        predicates.and(activityDO.activitySignUpType.eq(ActivitySignUpTypeEnum.SUPPLIER.getCode()));

        // activityDO
        predicates.and(activityDO.outerStatus.eq(PlatformActivityOuterStatusEnum.TO_BE_EXAMINE_SIGN_UP.getCode()));

        // 报名内部状态为待审核, 审核一级不通过, 审核二级不通过
        List<Integer> innerStatusList = Arrays.asList(PlatformActivitySignUpInnerStatusEnum.TO_BE_SUBMIT_EXAMINE.getCode(),
                PlatformActivitySignUpInnerStatusEnum.EXAMINE_NO_PASS_1.getCode(),
                PlatformActivitySignUpInnerStatusEnum.EXAMINE_NO_PASS_2.getCode());

        // platformSignUpDO
        BooleanBuilder signUpDOPredicates = new BooleanBuilder();
        signUpDOPredicates.or(signUpDO.id.isNull());
        signUpDOPredicates.or(signUpDO.status.in(innerStatusList));
        signUpDOPredicates.or(
                signUpDO.outerExtendStatus.eq(PlatformActivitySignUpOuterStatusEnum.SIGN_UP_NO_PASS.getCode())
                        .and(signUpDO.status.eq(PlatformActivitySignUpInnerStatusEnum.SUBMITTED.getCode()))
        );
        predicates.and(signUpDOPredicates);

        // 子查询 - 邀请会员
        BooleanBuilder inviteDOSubPredicates = new BooleanBuilder();
        inviteDOSubPredicates.and(
                inviteDO.platformActivity.id.eq(activityDO.id).and(
                        inviteDO.memberId.eq(loginUser.getMemberId())
                                .and(inviteDO.roleId.eq(loginUser.getMemberRoleId()))
                )
        );

        // 如果指定邀请会员,判断邀请名单, 否则不判断
        predicates.and(activityDO.inviteType.eq(CommonBooleanEnum.NO.getCode())
                .and(JPAExpressions.select(inviteDO).from(inviteDO).where(inviteDOSubPredicates).exists())
                .or(activityDO.inviteType.eq(CommonBooleanEnum.YES.getCode())));

        if (StringUtils.isNotEmpty(pageReq.getStartTime())) {
            Long startTime = DateTimeUtil.toMilliSecond(DateTimeUtil.parseDateStart(pageReq.getStartTime()));
            predicates.and(activityDO.startTime.goe(startTime));
        }

        if (StringUtils.isNotEmpty(pageReq.getEndTime())) {
            Long endTime = DateTimeUtil.toMilliSecond(DateTimeUtil.parseDateEnd(pageReq.getEndTime()));
            predicates.and(activityDO.startTime.loe(endTime));
        }

        if (StringUtils.isNotEmpty(pageReq.getActivityName())) {
            predicates.and(activityDO.activityName.like("%" + pageReq.getActivityName().trim() + "%"));
        }

        if (Objects.nonNull(pageReq.getId())) {
            predicates.and(activityDO.id.eq(pageReq.getId()));
        }

        if (Objects.nonNull(pageReq.getActivityType())) {
            predicates.and(activityDO.activityType.eq(pageReq.getActivityType()));
        }

        JPAQuery<PfActivitySignUpPageBO> queryJpaQuery = queryFactory.select(Projections.bean(PfActivitySignUpPageBO.class,
                activityDO.id.as("activityId"),
                activityDO.activityName,
                activityDO.activityType,
                activityDO.outerStatus.as("activityOuterStatus"),
                activityDO.startTime,
                activityDO.endTime,
                activityDO.signUpStartTime,
                activityDO.signUpEndTime,
                activityDO.createTime.as("activityCreateTime"),
                signUpDO.id.as("signUpId"),
                signUpDO.memberId.as("signUpMemberId"),
                signUpDO.roleId.as("signUpRoleId"),
                signUpDO.outerExtendStatus.as("signUpOuterExtendStatus"),
                signUpDO.status.as("signUpInnerStatus"),
                signUpDO.createTime.as("signUpCreateTime")))
                .from(activityDO)
                .leftJoin(signUpDO).on(activityDO.id.eq(signUpDO.platformActivity.id).and(signUpDO.memberId.eq(loginUser.getMemberId()).and(signUpDO.roleId.eq(loginUser.getMemberRoleId()))));

        queryJpaQuery.where(predicates);

        //总条数
        long totalCount = queryJpaQuery.fetchCount();
        List<PfActivitySignUpPageBO> pageList = queryJpaQuery.orderBy(activityDO.createTime.desc())
                .offset(pageReq.getCurrentOffset())
                .limit(pageReq.getPageSize())
                .fetch();

        return new PageData<>(totalCount, pageList);
    }

    /**
     * 待新增平台营销活动 - 提交
     * @param loginUser 登录用户信息
     * @param platformActivityDOList 平台活动报名
     */
    protected void baseSubmit(UserLoginCacheDTO loginUser, List<PlatformActivityDO> platformActivityDOList) {
        long currentTimeMillis = System.currentTimeMillis();
        for (PlatformActivityDO platformActivityDO : platformActivityDOList) {
            // 判断活动参与类型
            if (ActivitySignUpTypeEnum.SUPPLIER.getCode().equals(platformActivityDO.getActivitySignUpType())) {
                // 执行外部流转
                platformActivityDO = processFeignService.completeSimpleTaskByPlatformActivityOuter(platformActivityDO, ProcessTaskStatusEnum.AGREE.getCode());
            } else {
                // 执行外部流转
                platformActivityDO = processFeignService.completeSimpleTaskByPlatformActivityOuter(platformActivityDO, ProcessTaskStatusEnum.DISAGREE.getCode());
            }

            // 外部流转记录
            activityRecordService.savePlatformActivityOuterRecord(loginUser, platformActivityDO.getId(), platformActivityDO.getOuterStatus(), PlatformActivityOuterStatusEnum.getMessage(platformActivityDO.getOuterStatus()), ActivityStrOperateEnum.pt_outer_add.getMessage(), "");

            // 执行内部状态变更
            platformActivityDO.setInnerStatus(PlatformActivityInnerStatusEnum.SUBMITTED.getCode());
            platformActivityRepository.saveAndFlush(platformActivityDO);

            // 内部流转记录
            activityRecordService.savePlatformActivityInnerRecord(loginUser, platformActivityDO.getId(), platformActivityDO.getInnerStatus(), PlatformActivityInnerStatusEnum.getMessage(platformActivityDO.getInnerStatus()), ActivityStrOperateEnum.pt_inner_add.getMessage(), "");

            if (ActivitySignUpTypeEnum.SUPPLIER.getCode().equals(platformActivityDO.getActivitySignUpType())) {
                if (currentTimeMillis <= platformActivityDO.getSignUpStartTime()) {
                    // 报名时间前
                    // 定时任务, [报名时间开始]触发状态变更为: 待报名 -> 待审核报名
                    scheduleFeignService.createSignUpStartTask(loginUser, platformActivityDO);

                    // 定时任务, [报名时间结束]触发状态变更为: 待审核报名 -> 待上线活动
                    scheduleFeignService.createSignUpEndTask(loginUser, platformActivityDO);
                } else if (currentTimeMillis >= platformActivityDO.getSignUpStartTime() && currentTimeMillis <= platformActivityDO.getSignUpEndTime()) {
                    // 报名时间中
                    // 如果当前时间已经到了报名时间内, 则执行工作流, 待报名 -> 待审核报名
                    platformActivityDO = processFeignService.completeSimpleTaskByPlatformActivityOuter(platformActivityDO, ProcessTaskStatusEnum.GOTO_NEXT_STEP.getCode());
                    platformActivityDO.setInnerStatus(PlatformActivityInnerStatusEnum.TO_BE_EXAMINE_SIGN_UP.getCode());
                    platformActivityRepository.saveAndFlush(platformActivityDO);

                    // 定时任务, [报名时间结束]触发状态变更为: 待审核报名 -> 待上线活动
                    scheduleFeignService.createSignUpEndTask(loginUser, platformActivityDO);
                }
            }
        }
    }

    /**
     * 审核报名资料(一级) - 审核
     * @param loginUser 登录用户信息
     * @param signUpDOList 平台活动报名
     * @param agree 是否审核通过
     * @param opinion 审核意见
     */
    protected void baseExamineStep1(UserLoginCacheDTO loginUser, List<PlatformActivitySignUpDO> signUpDOList, Integer agree, String opinion) {
        for (PlatformActivitySignUpDO signUpDO : signUpDOList) {
            // 执行内部工作流
            TaskExecuteVO taskStartVO = new TaskExecuteVO();
            taskStartVO.setProcessKey(signUpDO.getProcessKey());
            taskStartVO.setMemberId(MemberRoleEnum.PLATFORM.getMemberId());
            taskStartVO.setRoleId(MemberRoleEnum.PLATFORM.getRoleId());
            taskStartVO.setDataId(signUpDO.getId());
            taskStartVO.setAgree(agree);
            taskStartVO.setTaskId(signUpDO.getTaskId());
            Wrapper<SimpleTaskCompleteVO> taskResult = processFeignService.completeSimpleTask(taskStartVO);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                throw new BusinessException(ResponseCode.WF_PROCESS_SERVICE_EXCEPTION);
            }
            signUpDO.setTaskId(taskResult.getData().getTaskId());
            signUpDO.setStatus(taskResult.getData().getStatus());
            signUpDO.setUpdateTime(System.currentTimeMillis());

            signUpRepository.saveAndFlush(signUpDO);

            // 内部流程记录
            activityRecordService.savePlatformActivitySignUpInnerRecord(loginUser, signUpDO.getPlatformActivity().getId(), signUpDO.getId(), taskResult.getData().getStatus(),
                    PlatformActivitySignUpInnerStatusEnum.getMessage(signUpDO.getStatus()), ActivityStrOperateEnum.pt_inner_signup_examine_step1.getMessage(), "");
        }
    }

    /**
     * 审核报名资料(二级) - 审核
     * @param loginUser 登录用户信息
     * @param signUpDOList 平台活动报名
     * @param agree 是否审核通过
     * @param opinion 审核意见
     */
    protected void baseExamineStep2(UserLoginCacheDTO loginUser, List<PlatformActivitySignUpDO> signUpDOList, Integer agree, String opinion) {
        for (PlatformActivitySignUpDO signUpDO : signUpDOList) {
            // 执行内部工作流
            TaskExecuteVO taskStartVO = new TaskExecuteVO();
            taskStartVO.setProcessKey(signUpDO.getProcessKey());
            taskStartVO.setMemberId(MemberRoleEnum.PLATFORM.getMemberId());
            taskStartVO.setRoleId(MemberRoleEnum.PLATFORM.getRoleId());
            taskStartVO.setDataId(signUpDO.getId());
            taskStartVO.setAgree(agree);
            taskStartVO.setTaskId(signUpDO.getTaskId());
            Wrapper<SimpleTaskCompleteVO> taskResult = processFeignService.completeSimpleTask(taskStartVO);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                throw new BusinessException(ResponseCode.WF_PROCESS_SERVICE_EXCEPTION);
            }
            signUpDO.setTaskId(taskResult.getData().getTaskId());
            signUpDO.setStatus(taskResult.getData().getStatus());
            signUpDO.setUpdateTime(System.currentTimeMillis());

            signUpRepository.saveAndFlush(signUpDO);

            // 内部流程记录
            activityRecordService.savePlatformActivitySignUpInnerRecord(loginUser, signUpDO.getPlatformActivity().getId(), signUpDO.getId(), taskResult.getData().getStatus(),
                    PlatformActivitySignUpInnerStatusEnum.getMessage(signUpDO.getStatus()), ActivityStrOperateEnum.pt_inner_signup_examine_step2.getMessage(), "");
        }
    }

    /**
     * 待提交报名资料 - 提交
     * @param loginUser 登录用户信息
     * @param signUpDOList 平台活动报名
     */
    protected void baseSubmitSignUp(UserLoginCacheDTO loginUser, List<PlatformActivitySignUpDO> signUpDOList) {
        for (PlatformActivitySignUpDO signUpDO : signUpDOList) {
            // 执行内部工作流
            TaskExecuteVO taskStartVO = new TaskExecuteVO();
            taskStartVO.setProcessKey(signUpDO.getProcessKey());
            taskStartVO.setMemberId(MemberRoleEnum.PLATFORM.getMemberId());
            taskStartVO.setRoleId(MemberRoleEnum.PLATFORM.getRoleId());
            taskStartVO.setDataId(signUpDO.getId());
            taskStartVO.setAgree(ProcessTaskStatusEnum.GOTO_NEXT_STEP.getCode());
            taskStartVO.setTaskId(signUpDO.getTaskId());
            Wrapper<SimpleTaskCompleteVO> taskResult = processFeignService.completeSimpleTask(taskStartVO);
            if (ResponseCode.SUCCESS.getCode() != taskResult.getCode()) {
                throw new BusinessException(ResponseCode.WF_PROCESS_SERVICE_EXCEPTION);
            }
            signUpDO.setTaskId(taskResult.getData().getTaskId());
            signUpDO.setStatus(taskResult.getData().getStatus());
            signUpDO.setUpdateTime(System.currentTimeMillis());
            signUpRepository.saveAndFlush(signUpDO);

            // 内部流程记录
            activityRecordService.savePlatformActivitySignUpInnerRecord(loginUser, signUpDO.getPlatformActivity().getId(), signUpDO.getId(), taskResult.getData().getStatus(),
                    taskResult.getData().getStatusDesc(), ActivityStrOperateEnum.pt_inner_signup_submit_to_platform.getMessage(), "");

            // 外部流程记录
            PlatformActivityOuterStatusEnum submitSignUpOuterStatus = PlatformActivityOuterStatusEnum.TO_BE_EXAMINE_SIGN_UP;
            activityRecordService.savePlatformActivitySignUpOuterRecord(loginUser, signUpDO.getPlatformActivity().getId(), signUpDO.getId(),
                    submitSignUpOuterStatus.getCode(), submitSignUpOuterStatus.getMessage(), ActivityStrOperateEnum.pt_outer_submit_signup.getMessage(), "");
        }
    }

    /**
     * 校验活动支持的会员类型
     * @param loginUser 登录用户信息
     * @return true, false
     */
    protected boolean checkMemberSupport(UserLoginCacheDTO loginUser) {
        // 平台活动不支持渠道会员
        return MemberTypeEnum.MERCHANT.getCode().equals(loginUser.getMemberType())
                || MemberTypeEnum.MERCHANT_PERSONAL.getCode().equals(loginUser.getMemberType());
    }
}